package com.liuguang.rabbitmq.config;

import com.liuguang.common.constans.CommonConstans;
import org.apache.dubbo.common.constants.CommonConstants;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName: RabbitMqConfig
 * @Description：
 * @Author: wanghr
 * Date: 10:40 AM 2020/10/14
 * Version: 1.0
 */
@Configuration
public class RabbitMqConfig {
    @Autowired
    private MyConfrimCallback myConfrimCallback;

    @Autowired
    private MyReturnCallback myReturnCallback;

    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        if (connectionFactory instanceof CachingConnectionFactory) {
            CachingConnectionFactory cachingConnectionFactory = (CachingConnectionFactory) connectionFactory;

            boolean publisherConfirms = cachingConnectionFactory.isPublisherConfirms();
            System.out.println("publisherConfirms = " + publisherConfirms);

            boolean publisherReturns = cachingConnectionFactory.isPublisherReturns();
            System.out.println("publisherReturns = " + publisherReturns);

            boolean publisherConfirms1 = cachingConnectionFactory.isSimplePublisherConfirms();
            System.out.println("isSimplePublisherConfirms = " + publisherConfirms1);

            cachingConnectionFactory.setPublisherConfirms(true);
            cachingConnectionFactory.setPublisherReturns(true);
        }
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setConfirmCallback(myConfrimCallback);
        rabbitTemplate.setReturnCallback(myReturnCallback);
        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
        rabbitTemplate.setUsePublisherConnection(true);
        return rabbitTemplate;
    }

    /**
     * 声明 direct  交换机,支持持久化
     *
     * @params: []
     * @return: org.springframework.amqp.core.Exchange
     */
    @Bean("directExchange")
    public Exchange directExchange() {
        return ExchangeBuilder.directExchange(CommonConstans.DIRECT_EXCHANGE_NAME).durable(true).build();
    }

    /**
     * 声明死信交换机
     */
    @Bean("deadLetterExchange")
    public Exchange deadLetterExchange() {
        return ExchangeBuilder.directExchange(CommonConstans.DEAD_LETTER_EXCHANGE).durable(true).build();
    }

    /**
     * 声明 邮件 队列
     *
     * @params: []
     * @return: Queue
     */
    @Bean("emailQueue")
    public Queue emailQueue() {
        return QueueBuilder.durable(CommonConstans.EMAIL_QUEUE_NAME).build();
    }

    /**
     * 测试队列
     *
     * @params:
     * @return: org.springframework.amqp.core.Queue
     */
    @Bean("testQueue")
    public Queue testQueue() {
        Map<String, Object> args = new HashMap<>(4);
//        // 当前队列绑定到死信交换机
        args.put("x-dead-letter-exchange", CommonConstans.DEAD_LETTER_EXCHANGE);
//        // 当前队列的死信路由
        args.put("x-dead-letter-routing-key", CommonConstans.DEAD_LETTER_ROUTING_KEY);
        return QueueBuilder.durable(CommonConstans.TEST_QUEUE).withArguments(args).build();
//        return QueueBuilder.durable(CommonConstans.TEST_QUEUE).build();
    }

    /**
     * 死信队列
     *
     * @params:
     * @return: org.springframework.amqp.core.Queue
     */
    @Bean("deadLetterQueue")
    public Queue deadLetterQueue() {
        return QueueBuilder.durable(CommonConstans.DEAD_LETTER_QUEUE).build();
    }


    /**
     * 绑定 邮件队列 到 交换机
     *
     * @params: [queue, exchange]
     * @return: org.springframework.amqp.core.Binding
     */
    @Bean
    public Binding bindEmailQueueToDirectExchange(@Qualifier("emailQueue") Queue queue, @Qualifier("directExchange") Exchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(CommonConstans.EMAIL_ROUTING_KEY).noargs();
    }

    /**
     * 绑定 测试队列 到 direct 交换机
     *
     * @params: [queue, exchange]
     * @return: org.springframework.amqp.core.Binding
     */
    @Bean
    public Binding bindTestQueueToDirectExchange(@Qualifier("testQueue") Queue queue, @Qualifier("directExchange") Exchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(CommonConstans.TEST_ROUTING_KEY).noargs();
    }

    /**
     * 绑定 死信队列 到 死信 direct 交换机
     *
     * @params: [queue, exchange]
     * @return: org.springframework.amqp.core.Binding
     */
    @Bean
    public Binding bindDeadLetterQueueToDeadLetterDirectExchange(@Qualifier("deadLetterQueue") Queue queue, @Qualifier("deadLetterExchange") Exchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(CommonConstans.DEAD_LETTER_ROUTING_KEY).noargs();
    }
}
